use axum::{
  Router, debug_handler, extract::State, response::IntoResponse, routing::get,
};

mod config;
mod database;
mod logger;

mod entity;
use entity::{company, prelude::*};
use sea_orm::{Condition, prelude::*};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
  logger::init();
  let db = database::init().await?;

  let app = Router::new()
    .route("/", get(index))
    .route("/demo", get(query_users))
    .with_state(db);
  let port = config::get().server().port();

  let addr = format!("0.0.0.0:{port}");
  let listener = tokio::net::TcpListener::bind(&addr).await?;
  tracing::info!("Listening on http://{addr}");
  axum::serve(listener, app).await?;

  Ok(())
}

// RUST_LOG=debug cargo run
#[debug_handler]
async fn index() -> &'static str {
  "World, Hello!"
}

// RUST_LOG=debug cargo run
#[debug_handler]
async fn query_users(
  State(db): State<DatabaseConnection>,
) -> impl IntoResponse {
  // let users = Company::find().all(&db).await.unwrap();
  // let users = Company::find()
  //   .filter(company::Column::Name.eq("Teddy"))
  //   .all(&db)
  //   .await
  //   .unwrap();
  // let users = Company::find()
  //   .filter(
  //     Condition::all()
  //       .add(company::Column::Age.eq(27))
  //       .add(company::Column::Name.starts_with("D")),
  //   )
  //   .all(&db)
  //   .await
  //   .unwrap();
  let users = Company::find()
    .filter(
      Condition::all()
        .add(company::Column::Age.eq(27))
        .add(company::Column::Name.starts_with("D"))
        .add(Condition::any().add(company::Column::Salary.eq(85000.0))),
    )
    .all(&db)
    .await
    .unwrap();
  axum::Json(users)
}
